package example.fileupload3;

import grpc.htsoft.fileupload.FileServiceGrpc;
import grpc.htsoft.fileupload.FileUploadRequest;
import grpc.htsoft.fileupload.FileUploadResponse;
import grpc.htsoft.fileupload.Status;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class fileuploadserver {


    public static void main(String[] args) throws IOException, InterruptedException {
        System.out.println("server3");
        Server server = ServerBuilder.forPort(50093)
                .addService(new FileUploadService())
                .build();
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            System.out.println("gRPC server is shutting down!");
            server.shutdown();
        }));

        System.out.println("Starting server...");
        server.start();
        System.out.println("Server started!");
        server.awaitTermination();
    }

    //定义一个上传的服务
    public static class FileUploadService extends FileServiceGrpc.FileServiceImplBase {
        //继承FileServiceGrpc.FileServiceImplBase类，实现upload方法
        private  final Path SERVER_BASE_PATH = Paths.get("/Users/zgw/temp/");
        @Override
        public StreamObserver<FileUploadRequest> upload(StreamObserver<FileUploadResponse> responseObserver) {
            StreamObserver<FileUploadRequest> fileUploadRequestStreamObserver = new StreamObserver<FileUploadRequest>() {
                OutputStream writer;
                Status status = Status.IN_PROGRESS;
//                {
//                    try {
//                        output = new OutputStream("/Users/zgw/temp/a.png");
//                    } catch (IOException e) {
//                        e.printStackTrace();
//                    }
//                }
                @Override
                public void onNext(FileUploadRequest fileUploadRequest) {
                    System.out.println("File onNext: ");
                    if(fileUploadRequest.hasMetadata()){
                        var fileName = fileUploadRequest.getMetadata().getName() + "." + fileUploadRequest.getMetadata().getType();
                        try {
                            writer = Files.newOutputStream(SERVER_BASE_PATH.resolve(fileName), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    }else{
                        try {
                            if(writer == null){
                                throw new RuntimeException("File path is not set");
                            }
                            writer.write(fileUploadRequest.getFile().getContent().toByteArray());
                            writer.flush();
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }

                    }
                }

                @Override
                public void onError(Throwable throwable) {
                    System.out.println("File onError: ");
                    this.onCompleted();
                }

                @Override
                public void onCompleted() {
                    System.out.println("File onCompleted: ");
                    try {
                        writer.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    status = Status.IN_PROGRESS.equals(status) ? Status.SUCCESS : status;
                    FileUploadResponse response = FileUploadResponse.newBuilder()
                            .setStatus(status)
                            .build();
                    responseObserver.onNext(response);
                    responseObserver.onCompleted();
                }
            };

            return fileUploadRequestStreamObserver;


        }
    }
}
